home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / pcx_c.zip / EGA.C < prev    next >
C/C++ Source or Header  |  1988-04-17  |  5KB  |  242 lines

  1. /*    EGA   -  routines to drive the EGA board.
  2. */
  3.  
  4. #include "lib.h"
  5. #include "vgr.h"
  6.  
  7. /*    proto's
  8. */
  9. int ega_init();
  10. int ega_select_plane();
  11. int ega_write_row();
  12. int ega_clear();
  13. int ega_set_palette();
  14. int ega_clr_point();
  15. int ega_xor_point();
  16. int ega_get_point();
  17. int ega_set_point();
  18. int ega_mode();
  19. int ega_null();
  20. int movmem();
  21. int peekb();
  22. int pokeb();
  23. int vgr_mode();
  24.  
  25. static int (*ega_func[])() = {
  26.     ega_init,       ega_clear,     ega_set_point, ega_clr_point,
  27.     ega_xor_point,  ega_get_point, ega_write_row, ega_select_plane,
  28.     ega_set_palette,ega_mode,      movmem, peekb, pokeb,
  29.     ega_null,       ega_null       };
  30.  
  31.  
  32. /*    EGA stuff
  33. */
  34.  
  35. #define REG_ADDRESS 0x3c4
  36. #define REG_MAPMASK 0x3c5
  37. #define REG_IDX     0x3ce
  38. #define REG_VAL     0x3cf
  39. #define OUTIDX(i,v) {outportb(REG_IDX,i);outportb(REG_VAL,v);}
  40.  
  41. static unsigned char far * far *ega_column;
  42.  
  43.  
  44. static int ega_null()
  45. {
  46.     return ERROR;
  47. }
  48.  
  49. int ega_init()
  50. {
  51.     void *malloc();
  52.     int row;
  53.  
  54.     if ( !ega_column )
  55.        ega_column = CASTUCFPP malloc( sizeof CASTUCFP * 350 );
  56.  
  57.     if ( !ega_column )
  58.        return ERROR;
  59.  
  60.     for ( row = 0; row < 350; row++ )
  61.        ega_column[row] = CASTUCFP BASE_EGA + row*80l;
  62.  
  63.     VGR_HRES   = 640;
  64.     VGR_VRES   = 350;
  65.     VGR_NBPL   =  80;
  66.     VGR_NCOLORS = 16;
  67.  
  68.     movmem( ega_func, vgr_func, sizeof(vgr_func) );
  69.     return OK;
  70. }
  71.  
  72.  
  73. int ega_select_plane( plane )
  74. int plane;
  75. {
  76.     outportb( REG_ADDRESS, 2 );
  77.     outportb( REG_MAPMASK, plane >= 0 ? 1 << (plane & 0x03) : -plane );
  78. }
  79.  
  80.  
  81. /*    A version for the CGA card will have to check for retrace
  82.     before copying each byte.
  83. */
  84. int ega_write_row( row, prow, nbytes )
  85. register unsigned int nbytes;
  86. unsigned char *prow;
  87. int row;
  88. {
  89.     movmem( prow, ega_column[row], nbytes );
  90. }
  91.  
  92.  
  93. int ega_clear()
  94. {
  95.     ega_select_plane( -0x0f );
  96.     setmem( BASE_EGA, 0x8000, 0 );
  97.     ega_select_plane( 0 );
  98. }
  99.  
  100.  
  101. int ega_set_palette( reg, red, green, blue )
  102. unsigned char reg, red, green, blue;
  103. {
  104.     REGS r;
  105.     unsigned char v;
  106.  
  107.     v = (blue  & 0x01)     | (blue  & 0x02) *  4
  108.       | (green & 0x01) * 2 | (green & 0x02) *  8
  109.       | (red   & 0x01) * 4 | (red   & 0x02) * 16;
  110.  
  111.     r.ax = 0x1000;
  112.     r.bx = ((unsigned int)v << 8) | reg;
  113.     sysint( 0x10, &r, &r );
  114. }
  115.  
  116.  
  117. int ega_clr_point( x, y )
  118. unsigned int x, y;
  119. {
  120.     ega_set_point( x, y, 0 );
  121. }
  122.  
  123.  
  124. int ega_xor_point( x, y, color )
  125. unsigned int x, y, color;
  126. {
  127.     ega_set_point( x, y, ega_get_point( x, y ) ^ color );
  128. }
  129.  
  130.  
  131. int ega_get_point( x, y )
  132. unsigned int x, y;
  133. {
  134. #if 1
  135.     REGS r;
  136.  
  137.     r.ax = 0x0d00;
  138.     r.dx = y;
  139.     r.cx = x;
  140.  
  141.     sysint( 0x10, &r, &r );
  142.     return r.ax & 0xff;
  143. #endif
  144. #if 0
  145.     unsigned char plane, mask, b, color;
  146.     unsigned char far *p;
  147.  
  148.     p = ega_column[y] + (x>>3);
  149.     b = 0x80 >> (x & 0x07);
  150.  
  151.     outportb( REG_ADDRESS, 2 );
  152.  
  153.     for ( color=plane=0; plane < 4; plane++ )
  154.     {  outportb( REG_MAPMASK, mask = (1 << plane) );
  155.        color |= !!(*p & b) * mask;
  156.     };
  157.  
  158.     return color;
  159. #endif
  160. }
  161.  
  162.  
  163. int ega_set_point( x, y, color )
  164. unsigned int x, y, color;
  165. {
  166. #if 1
  167.     /* this works, but is painfully slow!! */
  168.     REGS r;
  169.  
  170.     r.ax = 0x0c00 | color;
  171.     r.dx = y;
  172.     r.cx = x;
  173.  
  174.     sysint( 0x10, &r, &r );
  175.     return OK;
  176. #endif
  177. #if 0
  178.     /* This is my routine. It works if you stick to the color white!
  179.        otherwise, it doesn't work because it's apparently not possible
  180.        to directly read the EGA VRAM.
  181.     */
  182.     unsigned char plane, mask, b;
  183.     unsigned char far *p;
  184.  
  185.     p = ega_column[y] + (x>>3);
  186.     b = (unsigned int)0x80 >> (x & 0x07);
  187.  
  188.     outportb( REG_ADDRESS, 2 );
  189.  
  190.     for ( plane=0; plane < 4; plane++ )
  191.     {  outportb( REG_MAPMASK, mask = ((unsigned int)1 << plane) );
  192.        if ( color & mask )
  193.           *p |= b;
  194.        else *p &= ~b;
  195.     };
  196. #endif
  197. #if 0
  198.     /* This is Gary Entsmingers routine,
  199.        which works like an XOR function instead of
  200.        a set function. I don't have the foggiest
  201.        notion how it works. There's no reference in
  202.        any of the (incomplete) doc that I've got
  203.        to the registers used here.
  204.     */
  205.     unsigned char b;
  206.     unsigned char far *p;
  207.  
  208.     p = ega_column[y] + (x>>3);
  209.     b = (unsigned int)0x80 >> (x & 0x07);
  210.  
  211.     OUTIDX(0,color);
  212.     OUTIDX(1, 0x0f);
  213.     OUTIDX(8,    b);
  214.     OUTIDX(3, 0x18);
  215.  
  216.     /* It doesn't seem to matter what you do here as long as you
  217.        don't assign -1 to *p. *p |= -1, *p &= -1, *p ^= *p and *p = *p
  218.        all have the same effect - a hardware XOR function!
  219.     */
  220.     *p &= 0xff;
  221.  
  222.     OUTIDX(0,0);
  223.     OUTIDX(1,0);
  224.     OUTIDX(8,0xff);
  225.     OUTIDX(3,0);
  226. #endif
  227. }
  228.  
  229.  
  230. int ega_mode( mode )
  231. int mode;
  232. {
  233.     if ( mode == MODE_APA0 )
  234.        return vgr_mode( 16 );
  235.  
  236.     if ( mode == MODE_TEXT0 )
  237.        return vgr_mode( 3 );
  238.  
  239.     return ERROR;  /* mode not currently supported */
  240. }
  241.  
  242.